package cn.foxtech.cloud.repo.comp.haas.service;


import cn.craccd.mongoHelper.bean.Page;
import cn.craccd.mongoHelper.bean.SortBuilder;
import cn.craccd.mongoHelper.bean.UpdateBuilder;
import cn.craccd.mongoHelper.utils.CriteriaAndWrapper;
import cn.craccd.mongoHelper.utils.CriteriaOrWrapper;
import cn.craccd.mongoHelper.utils.CriteriaWrapper;
import cn.foxtech.cloud.common.mongo.entity.EdgeEntity;
import cn.foxtech.cloud.common.utils.mongo.MongoExHelper;
import cn.foxtech.cloud.core.constant.Constant;
import cn.foxtech.cloud.core.exception.ServiceException;
import cn.foxtech.cloud.repo.comp.haas.constants.ConstantRepoCompHaas;
import cn.foxtech.cloud.repo.comp.haas.constants.ConstantRepoCompHaasVersion;
import cn.foxtech.cloud.repo.comp.haas.entity.RepoCompHaasEntity;
import cn.foxtech.cloud.repo.comp.haas.entity.RepoCompHaasVersionEntity;
import cn.foxtech.common.utils.method.MethodUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class RepoCompHaasVersionService {
    @Autowired
    private MongoExHelper mongoHelper;


    @Autowired
    private RepoCompHaasService haasService;

    @Autowired
    private RepoCompHaasFileService fileService;


    public void initialize() {
        List<String> indexFields = new ArrayList<>();

        // 创建数据库表：如果不存在则创建，存在则跳过
        this.mongoHelper.createCollection(ConstantRepoCompHaasVersion.field_collection_name, indexFields);
    }

    public void insertVersionEntity(RepoCompHaasVersionEntity entity) {
        if (MethodUtils.hasEmpty(entity.getAuthor(), entity.getHaasId())) {
            throw new ServiceException("参数不能为空: haasId, author");
        }

        // 写入数据库
        this.mongoHelper.insert(ConstantRepoCompHaasVersion.field_collection_name, entity);
    }

    public List<RepoCompHaasVersionEntity> queryEntityList(CriteriaWrapper criteriaWrapper) {
        SortBuilder sortBuilder = new SortBuilder(RepoCompHaasEntity::getCreateTime, Sort.Direction.DESC);
        List<RepoCompHaasVersionEntity> result = this.mongoHelper.findListByQuery(criteriaWrapper, sortBuilder, ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);
        return result;
    }

    public RepoCompHaasVersionEntity queryEntity(CriteriaWrapper criteriaWrapper, SortBuilder sortBuilder) {
        RepoCompHaasVersionEntity result = this.mongoHelper.findOneByQuery(criteriaWrapper, sortBuilder, ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);
        return result;
    }


    public CriteriaAndWrapper buildWrapper(Map<String, Object> param) {
        CriteriaAndWrapper andWrapper = new CriteriaAndWrapper();
        if (param.containsKey(ConstantRepoCompHaasVersion.field_id)) {
            andWrapper.eq(ConstantRepoCompHaasVersion.field_id, param.get(ConstantRepoCompHaasVersion.field_id));
        }
        if (param.containsKey(ConstantRepoCompHaasVersion.field_author)) {
            andWrapper.eq(ConstantRepoCompHaasVersion.field_author, param.get(ConstantRepoCompHaasVersion.field_author));
        }
        if (param.containsKey(ConstantRepoCompHaasVersion.field_haas_id)) {
            andWrapper.eq(ConstantRepoCompHaasVersion.field_haas_id, param.get(ConstantRepoCompHaasVersion.field_haas_id));
        }
        if (param.containsKey(ConstantRepoCompHaasVersion.field_haas_ids)) {
            andWrapper.in(ConstantRepoCompHaasVersion.field_haas_id, (Collection) param.get(ConstantRepoCompHaasVersion.field_haas_ids));
        }
        if (param.containsKey(ConstantRepoCompHaasVersion.field_description)) {
            andWrapper.like(ConstantRepoCompHaasVersion.field_description, (String) param.get(ConstantRepoCompHaasVersion.field_description));
        }

        // 关键词查询：从这些文本字段中查询
        if (param.containsKey(ConstantRepoCompHaasVersion.field_keyword)) {
            CriteriaOrWrapper orWrapper = new CriteriaOrWrapper();
            orWrapper.like(ConstantRepoCompHaasVersion.field_author, (String) param.get(ConstantRepoCompHaasVersion.field_keyword));
            orWrapper.like(ConstantRepoCompHaasVersion.field_description, (String) param.get(ConstantRepoCompHaasVersion.field_keyword));

            andWrapper.and(orWrapper);
        }

        return andWrapper;
    }

    public Map<String, Object> queryPageList(CriteriaWrapper criteriaWrapper, Map<String, Object> body) {
        Integer pageNum = (Integer) body.get(Constant.field_page_num);
        Integer pageSize = (Integer) body.get(Constant.field_page_size);

        // 检查：是否至少包含以下几个参数
        if (MethodUtils.hasEmpty(pageNum, pageSize)) {
            throw new ServiceException("body参数缺失: pageNum, pageSize");
        }

        // 分页查询
        Page<EdgeEntity> page = new Page<>();
        page.setQueryCount(true);
        page.setCurr(pageNum);
        page.setLimit(pageSize);
        SortBuilder sortBuilder = new SortBuilder(RepoCompHaasVersionEntity::getCreateTime, Sort.Direction.DESC);
        Page<RepoCompHaasVersionEntity> result = this.mongoHelper.findPage(criteriaWrapper, sortBuilder, page, ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);

        // 将结果返回
        Map<String, Object> data = new HashMap<>();
        data.put("total", result.getCount());
        data.put("list", result.getList());


        return data;
    }

    public void updateEntity(String userName, Map<String, Object> param) {
        String id = (String) param.get(ConstantRepoCompHaas.field_id);
        if (MethodUtils.hasEmpty(id)) {
            throw new ServiceException("body参数缺失: id");
        }

        // 查询当前记录内容
        RepoCompHaasVersionEntity entity = this.mongoHelper.findById(id, ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);
        if (entity == null) {
            throw new ServiceException("找不到该版本实体");
        }

        // 查询当前记录内容
        RepoCompHaasEntity haasEntity = this.haasService.queryEntity(entity.getHaasId());
        if (haasEntity == null) {
            throw new ServiceException("找不到该HaaS实体");
        }

        // 只有author、owner和admin允许修改
        if (!userName.equals(haasEntity.getOwnerId()) && !userName.equals(entity.getAuthor()) && !userName.equals("admin")) {
            throw new ServiceException("只有author、admin和owner允许修改");
        }

        // 构造更新操作
        UpdateBuilder updateBuilder = new UpdateBuilder();

        if (param.containsKey(ConstantRepoCompHaasVersion.field_description)) {
            updateBuilder.set(RepoCompHaasVersionEntity::getDescription, param.get(ConstantRepoCompHaasVersion.field_description));
        }

        // 检查是否存在更新操作：如果没有更新操作，直接去更新，会出现清空记录的问题
        if (updateBuilder.toUpdate().getUpdateObject().isEmpty()) {
            return;
        }

        // 执行更新
        this.mongoHelper.updateById(entity.getId(), updateBuilder, ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);
    }

    public void delete(String userName, String id) {
        if (MethodUtils.hasEmpty(id)) {
            throw new ServiceException("参数缺失: id");
        }

        // 查询当前记录内容
        RepoCompHaasVersionEntity entity = this.mongoHelper.findById(id, ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);
        if (entity == null) {
            throw new ServiceException("找不到该版本实体");
        }

        // 查询当前记录内容
        RepoCompHaasEntity haasEntity = this.haasService.queryEntity(entity.getHaasId());
        if (haasEntity == null) {
            throw new ServiceException("找不到该HaaS实体");
        }

        // 只有author、owner和admin允许修改
        if (!userName.equals(haasEntity.getOwnerId()) && !userName.equals(entity.getAuthor()) && !userName.equals("admin")) {
            throw new ServiceException("只有author、admin和owner允许删除");
        }

        // 删除文件
        this.fileService.remove(haasEntity, entity.getFileName());

        this.mongoHelper.deleteById(entity.getId(), ConstantRepoCompHaasVersion.field_collection_name, RepoCompHaasVersionEntity.class);
    }

    public String getUri(RepoCompHaasEntity haasEntity, String fileName) {
        String uri = "/haas/";
        uri += haasEntity.getHardManufacturer() + "/";
        uri += haasEntity.getHardDeviceType() + "/";
        uri += haasEntity.getSoftManufacturer() + "/";
        uri += haasEntity.getSoftDeviceType() + "/";
        uri += fileName;
        return uri;
    }

}

